#pragma once
#include<pthread.h>
#include<string>
#include<iostream>
#include<functional>
#include<assert.h>


namespace myThread
{
    typedef std::function<void * (void*)> func_t;
    const int num = 1024;

    class Thread
    {
        static void* start_routine(void* args)
        {
            Thread* _this = static_cast<Thread*>(args);
            return _this->callback();
        }
    public:
        Thread()
        {
            char buffer[num];
            snprintf(buffer,sizeof buffer,"thread->%d",threadnum++);
            _name = buffer;
        }

        std::string threadname(){ return _name;}
        ~Thread(){}
        void* callback(){return _func(_args);}

        void start(func_t func,void* args = nullptr)
        {
            _func = func;
            _args = args;
            int n = pthread_create(&_tid,nullptr,start_routine,this);
            assert(n==0);
            (void)n;
        }

        void join()
        {
            int n = pthread_join(_tid,nullptr);
            assert(n==0);
            (void)n;
        }

    private:
        std::string _name;
        void* _args;
        func_t _func;
        pthread_t _tid;

        static int threadnum;
    };

    int Thread::threadnum = 1;
}